package javagprssrv.Listener;

import javagprssrv.StructClass.structRecvData;
import javagprssrv.Common.CommonClass;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import javagprssrv.StructClass.structTCPServerSocket;
import java.nio.channels.SelectionKey;
import java.net.ServerSocket;
import javagprssrv.JGS_Param;
import javagprssrv.Log;
import java.net.SocketAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;

public class TrdYiBiaoDataListener_TCP extends java.lang.Thread
{
    public int TCPServerSocketIndex;
    public java.lang.String RemoteIP;
    public int RemotePort;
    public java.lang.String Protocol;
    public java.lang.String SocketName;
    public int SocketPort;
    private java.nio.channels.ServerSocketChannel ServerChannel;
    private java.nio.channels.Selector selector;
    private int intActiveSocketCount;
    private final java.nio.ByteBuffer buffer;
    
    public TrdYiBiaoDataListener_TCP(final java.net.Socket _Client) {
        super("TrdYiBiaoDataListener_TCP");
        this.buffer = java.nio.ByteBuffer.allocate(65536);
    }
    
    public TrdYiBiaoDataListener_TCP(final java.lang.String _Protocol, final java.lang.String _SocketName, final int _SocketPort) {
        super("TrdYiBiaoDataListener_TCP");
        this.buffer = java.nio.ByteBuffer.allocate(65536);
        this.Protocol = _Protocol;
        this.SocketName = _SocketName;
        this.SocketPort = _SocketPort;
        this.intActiveSocketCount = 0;
        try {
            this.selector = java.nio.channels.Selector.open();
            this.ServerChannel = java.nio.channels.ServerSocketChannel.open();
            final java.net.ServerSocket socket = this.ServerChannel.socket();
            socket.bind(new java.net.InetSocketAddress(this.SocketPort));
            this.ServerChannel.configureBlocking(false);
            this.ServerChannel.register(this.selector, 16);
            boolean isBounded = false;
            if (socket.isBound()) {
                isBounded = true;
                new javagprssrv.Log().ShowLog(this.SocketName + "(" + this.Protocol + ":" + java.lang.Integer.valueOf(this.SocketPort).toString() + ") 打开成功。", true, true);
            }
            else {
                isBounded = false;
                java.lang.String strERR = "";
                final java.lang.String strLine = java.lang.System.getProperty("line.separator");
                strERR = this.SocketName + "(" + this.Protocol + ":" + java.lang.Integer.valueOf(this.SocketPort).toString() + ") 打开失败！" + strLine;
                strERR = strERR + "                    (建议)请使用“netstat -an”命令,查看" + java.lang.Integer.valueOf(this.SocketPort).toString() + "端口是否已经被使用。";
                javagprssrv.JGS_Param.myLog.ShowLog(strERR, true, true);
            }
        }
        catch (java.lang.Exception ex) {}
    }
    
    @java.lang.Override
    public void run() {
        try {
            while (true) {
                if (!javagprssrv.JGS_Param.isSystemReady) {
                    try {
                        java.lang.Thread.sleep(10L);
                    }
                    catch (java.lang.Exception e2) {}
                }
                else {
                    final int nKeys = this.selector.select();
                    if (nKeys == 0) {
                        continue;
                    }
                    final java.util.Iterator it = this.selector.selectedKeys().iterator();
                    while (it.hasNext()) {
                        java.nio.channels.SelectionKey key = null;
                        try {
                            key = (java.nio.channels.SelectionKey)(java.nio.channels.SelectionKey)it.next();
                            if (key.isAcceptable()) {
                                final java.nio.channels.ServerSocketChannel server = (java.nio.channels.ServerSocketChannel)key.channel();
                                final java.nio.channels.SocketChannel channel = server.accept();
                                if (channel == null) {
                                    continue;
                                }
                                channel.configureBlocking(false);
                                channel.register(this.selector, 1);
                                javagprssrv.StructClass.structTCPServerSocket SS = new javagprssrv.StructClass.structTCPServerSocket();
                                SS.ServerChannel = channel;
                                SS.RemoteIP = ((java.net.InetSocketAddress)channel.socket().getRemoteSocketAddress()).getAddress().getHostAddress();
                                SS.RemotePort = ((java.net.InetSocketAddress)channel.socket().getRemoteSocketAddress()).getPort();
                                SS.LocalPort = this.SocketPort;
                                javagprssrv.JGS_Param.TCPServerSockets.add(SS);
                                java.lang.String s = "[P=TCP,T=GET ,LocalPort = " + java.lang.String.valueOf(this.SocketPort) + ",S=";
                                s = s + SS.RemoteIP + ":";
                                s = s + java.lang.Integer.valueOf(SS.RemotePort).toString().trim() + "]  新TCP连接，已经建立完成！(new TCP Connection has been ACCEPT.)";
                                s = s + " ( Counts=" + java.lang.String.valueOf(javagprssrv.JGS_Param.TCPServerSockets.size()) + " ) ";
                                javagprssrv.JGS_Param.myLog.ShowLog(s, true, true);
                                SS = null;
                            }
                            if (key.isReadable()) {
                                this.readDataFromSocket(key);
                            }
                        }
                        catch (java.lang.Exception e) {
                            javagprssrv.JGS_Param.myLog.ShowLog("[ TrdJSSJDataListener_TCP ERROR (key.isAcceptable())]" + e.getMessage(), java.lang.Boolean.TRUE, java.lang.Boolean.TRUE);
                            try {
                                key.cancel();
                            }
                            catch (java.lang.Exception ex) {}
                        }
                        it.remove();
                    }
                }
            }
        }
        catch (java.lang.Exception e2) {
            e2.printStackTrace();
        }
    }
    
    private void readDataFromSocket(final java.nio.channels.SelectionKey key) {
        final int BUF_LENGTH = 10000;
        int readBytes = 0;
        int ret = -1;
        java.lang.String strRecv = "";
        try {
            java.nio.ByteBuffer buf = java.nio.ByteBuffer.allocate(BUF_LENGTH);
            final java.nio.channels.SocketChannel sc = (java.nio.channels.SocketChannel)key.channel();
            this.RemoteIP = ((java.net.InetSocketAddress)sc.socket().getRemoteSocketAddress()).getAddress().getHostAddress();
            this.RemotePort = ((java.net.InetSocketAddress)sc.socket().getRemoteSocketAddress()).getPort();
            try {
                while ((ret = sc.read(buf)) > 0) {
                    readBytes += ret;
                }
            }
            catch (java.lang.Exception ee) {}
            finally {
                buf.flip();
            }
            if (readBytes == 0) {
                sc.close();
                this.TCPServerSocketsRemoveByRemoteIPPort(this.RemoteIP, this.RemotePort);
                return;
            }
            strRecv = javagprssrv.Common.CommonClass.ByteBuffer2String(buf);
            buf.clear();
            buf = null;
        }
        catch (java.lang.Exception e) {
            e.printStackTrace();
        }
        java.lang.String s = "[P=TCP,T=GET " + java.lang.Integer.toString(readBytes) + ",LocalPort=" + java.lang.String.valueOf(this.SocketPort) + ",S=";
        s = s + this.RemoteIP + ":";
        s = s + java.lang.Integer.valueOf(this.RemotePort).toString().trim() + "] ";
        javagprssrv.JGS_Param.myLog.ShowLog(s + new javagprssrv.Log().String2HexString(strRecv, " "), true, true);
        javagprssrv.StructClass.structRecvData recvData = new javagprssrv.StructClass.structRecvData();
        recvData.Protocol = "TCP";
        recvData.RemoteIP = this.RemoteIP;
        recvData.RemotePort = this.RemotePort;
        recvData.Data = strRecv;
        javagprssrv.JGS_Param.UnDoneRecvDatas.add(recvData);
        recvData = null;
        this.setTCPDataThroughput(strRecv.length());
    }
    
    public synchronized void TCPServerSocketsRemoveByRemoteIPPort(final java.lang.String RemoteIP, final int RemotePort) {
        for (int i = 0; i < javagprssrv.JGS_Param.TCPServerSockets.size(); ++i) {
            final java.lang.String ip = ((structTCPServerSocket)javagprssrv.JGS_Param.TCPServerSockets.elementAt(i)).RemoteIP;
            final int port = ((structTCPServerSocket)javagprssrv.JGS_Param.TCPServerSockets.elementAt(i)).RemotePort;
            if (RemoteIP.equals(ip) && RemotePort == port) {
                javagprssrv.JGS_Param.TCPServerSockets.remove(i);
                java.lang.String s = "[P=TCP,T=GET ,LocalPort = " + java.lang.String.valueOf(this.SocketPort) + ",S=";
                s = s + RemoteIP + ":";
                s = s + java.lang.Integer.valueOf(RemotePort).toString().trim() + "]  TCP连接被关闭！(TCP Connection has been CLOSED.)";
                s = s + " ( Counts=" + java.lang.String.valueOf(javagprssrv.JGS_Param.TCPServerSockets.size()) + " ) ";
                javagprssrv.JGS_Param.myLog.ShowLog(s, true, true);
            }
        }
    }
    
    private synchronized void setTCPDataThroughput(final int DataSize) {
        long a = 0L;
        long b = 0L;
        long c = 0L;
        a = javagprssrv.JGS_Param.countReceiveData_TCP + DataSize;
        b = javagprssrv.JGS_Param.timesReceiveData_TCP + 1L;
        c = javagprssrv.JGS_Param.countReceiveData_All + DataSize;
        javagprssrv.JGS_Param.countReceiveData_TCP = a;
        javagprssrv.JGS_Param.timesReceiveData_TCP = b;
        javagprssrv.JGS_Param.countReceiveData_All = c;
    }
}
